package main

import (
	"docker_hosts/server"
	"docker_hosts/utils"
	"fmt"
	"io"
	"os"
	"path"
	"runtime"

	"github.com/kardianos/service"
	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	log "github.com/sirupsen/logrus"
)

type Program struct {
	exit chan struct{}
}

func (p *Program) Start(s service.Service) error {
	log.Printf("启动服务...%s", service.Platform())
	p.exit = make(chan struct{})
	go p.run()
	log.Printf("服务启动完成.")
	return nil
}
func (p *Program) Stop(s service.Service) error {
	log.Println("停止服务.")
	close(p.exit)
	return nil
}
func (p *Program) run() {
	log.Printf("服务运行中...")
	// 启动服务
	server.StartServer()
}

var (
	serviceName = "docker-hosts"
	action      string
	workDir     string
	exeName     string
)

func initLog(isService bool) {
	logPath := workDir + string(utils.PathSeparator) + exeName
	if isService {
		writer, _ := rotatelogs.New(
			logPath+".%Y-%m-%d.log",
			rotatelogs.WithLinkName(logPath+".log"),
			rotatelogs.WithRotationTime(utils.GetDurationTime("24h")),
			rotatelogs.WithRotationCount(10),
			rotatelogs.WithRotationSize(10*1024*1024),
		)
		writers := []io.Writer{
			writer,
			os.Stdout}
		//同时写文件和屏幕
		fileAndStdoutWriter := io.MultiWriter(writers...)
		log.SetOutput(fileAndStdoutWriter)
	}
	// 设置自定义的时间格式
	customFormat := "2006-01-02 15:04:05"
	log.SetFormatter(&log.TextFormatter{
		TimestampFormat: customFormat,
	})
	var level log.Level
	level.UnmarshalText([]byte("INFO"))
	log.Printf("日志级别:%v", level)
	log.SetLevel(level)
	log.Printf("工作目录:%s", workDir)
}

func isServiceAction(target string) bool {
	strArray := []string{"install", "uninstall", "start", "stop", "restart", "status"}
	for _, element := range strArray {
		if target == element {
			return true
		}
	}
	return false
}
func isAction(target string) bool {
	strArray := []string{"install", "uninstall", "start", "stop", "restart", "status", "run", "", "clear", "clean"}
	for _, element := range strArray {
		if target == element {
			return true
		}
	}
	return false
}
func initService() (service.Service, error) {
	//服务的配置信息
	options := make(service.KeyValue)
	options["LogOutput"] = true
	options["HasOutputFileSupport"] = true
	options["WorkingDirectory"] = workDir
	if runtime.GOOS == "windows" {
	} else {
		options["Restart"] = "on-failure"
		options["SuccessExitStatus"] = "1 2 8 SIGKILL"
	}
	svcConfig := &service.Config{
		Name:        serviceName,
		DisplayName: "docker-hosts监控服务",
		Description: "监控docker容器状态并更新hosts文件中容器名与ip对应关系",
		Option:      options,
		//Arguments :
	}
	if runtime.GOOS == "windows" {
	} else {
		svcConfig.Dependencies = []string{
			"Requires=network.target",
			"After=network-online.target syslog.target"}
		svcConfig.UserName = "root"
	}
	pro := &Program{}
	s, err := service.New(pro, svcConfig)
	return s, err
}
func main() {
	//初始化常用变量
	workDir = utils.GetExeFileDirectory()
	exeFile, _ := os.Executable()
	exeName = path.Base(exeFile)

	if len(os.Args) > 1 {
		action = os.Args[1]
	}
	if !isAction(action) {
		help()
		return
	}
	if action == "run" || action == "" {
		initLog(false)
		server.StartServer()
		return
	}
	//初始化日志
	initLog(true)
	if isServiceAction(action) {
		s, err := initService()
		if err != nil {
			log.Fatalf("初始化服务错误：%v", err)
		}
		errs := make(chan error, 5)
		_, err = s.SystemLogger(errs)
		if err != nil {
			log.Fatalf("初始化服务日志错误：%v", err)
		}
		go func() {
			for {
				err := <-errs
				if err != nil {
					log.Errorf("服务错误：%v", err)
				}
			}
		}()
		if action == "" {
			log.Printf("运行：%v", s)
			err = s.Run()
			if err != nil {
				log.Fatalf("发生错误：%v", err)
			}
		} else if action == "status" {
			status, err := s.Status()
			log.Printf("服务状态:%v  %s", status, " （0错误，1运行中，2停止）")
			if err != nil {
				log.Fatalf("读取服务状态失败:%v", err)
			}
		} else if action == "install" {
			err := s.Install()
			if err != nil {
				log.Fatalf("安装服务失败:%v", err)
			} else {
				log.Println("安装服务成功,服务名：" + serviceName)
			}
		} else if action == "uninstall" {
			err := s.Uninstall()
			if err != nil {
				log.Fatalf("卸载服务失败:%v", err)
			} else {
				log.Println("卸载服务成功")
			}
		} else if action == "start" {
			err := s.Start()
			if err != nil {
				log.Fatalf("启动服务失败:%v", err)
			} else {
				log.Printf("启动服务成功")
			}
			return
		} else if action == "stop" {
			err := s.Stop()
			if err != nil {
				log.Fatalf("停止服务失败:%v", err)
			} else {
				log.Printf("停止服务成功")
			}
			return
		} else if action == "restart" {
			err := s.Restart()
			if err != nil {
				log.Fatalf("重启服务失败:%v", err)
			} else {
				log.Println("重启服务成功")
			}
			return
		} else if action == "run" {
			err := s.Run()
			if err != nil {
				log.Fatal(err)
			}
			return
		}
	} else {
		help()
	}
}
func help() {
	fmt.Println("")
	fmt.Println("---------------命令使用说明--------------------------------")
	fmt.Println(exeName + " install 安装服务")
	fmt.Println(exeName + " uninstall 卸载服务")
	fmt.Println(exeName + " start 启动服务")
	fmt.Println(exeName + " stop 停止服务")
	fmt.Println(exeName + " restart 重启服务")
	fmt.Println(exeName + " status 查看服务状态")
	fmt.Println(exeName + " run 控制台运行")
	fmt.Println("--------------------------------------------------------")
	fmt.Println("")
}
